package tools

import java.io.{File, FileInputStream}
import java.nio.file.Files

import config.{Global, MyFile}
import org.apache.commons.io.{FileUtils, IOUtils}
import play.api.data.Form
import play.api.data.FormBinding.Implicits._
import play.api.data.Forms._
import play.api.libs.json.{JsObject, Json}
import play.api.mvc.{AnyContent, Request}
import play.shaded.oauth.org.apache.commons.codec.binary.Base64
import utils.{ExecCommand, PdfToImage}

import scala.jdk.CollectionConverters._

object GoKegg extends MyFile   {

  case class GoKeggData(species: String,id:String )

  val GoKeggForm: Form[GoKeggData] = Form(
    mapping(
      "species" -> text,
      "id" -> text
    )(GoKeggData.apply)(GoKeggData.unapply)
  )

  def goOrKegg(abbr:String)(implicit request: Request[AnyContent]): JsObject = {
    var valid = "true"
    var msg = ""
    var img1 = ""
    var img2 =""
    var table :Seq[Map[String,String]] = Seq()
    try {

      val tools = s"${Global.path}/tools/enrich"
      val enrich = s"${Global.path}/enrich"
      val data = GoKeggForm.bindFromRequest.get
      val tmpDir = Files.createTempDirectory("tmpDir").toString

      val geneIdFile = s"$tmpDir/GeneID.txt"
      val geneid = "Geneid" +: data.id.split(",").map(_.trim)
      FileUtils.writeLines(geneIdFile.toFile, geneid.toBuffer.asJava)

      val cmds = if (abbr == "kegg") {
        Array(s"perl $tools/kegg/kegg_enrich.pl $tmpDir $enrich/${data.species}.ko.xls")
      } else {
        Array(s"perl $tools/go/go_enrich.pl $tmpDir $enrich/${data.species}.go.xls")
      }
      cmds.foreach(println)

      val execCommand = new ExecCommand
      execCommand.exect(cmds, tmpDir)
      if (execCommand.isSuccess) {
        val (i1,i2,t) = if(abbr == "kegg"){
          PdfToImage.pdf2Png(s"Ko.enrich",tmpDir)
          PdfToImage.pdf2Png(s"ko_dodge",tmpDir)
          (s"$tmpDir/Ko.enrich.png",s"$tmpDir/ko_dodge.png", s"$tmpDir/Ko.Ko.enrich.xls")
        }else{
          PdfToImage.pdf2Png(s"go.Go.enrich",tmpDir)
          PdfToImage.pdf2Png(s"go_stack",tmpDir)
          (s"$tmpDir/go.Go.enrich.png",s"$tmpDir/go_stack.png", s"$tmpDir/go.Go.enrich.xls")
        }

        img1 = getBase64Str(i1.toFile)
        img2 = getBase64Str(i2.toFile)
        table = t.readLines.tail.map(_.split("\t").zipWithIndex.map(x=> x._2.toString -> x._1).toMap).toSeq
      } else {
        valid = "false"
        msg ="No Results!"
      }
      tmpDir.delete
    }catch {
      case e:Exception =>  valid = "false"; msg = e.getMessage
    }

    Json.obj("valid"->valid,"msg"->msg,"img1" -> img1,"img2" -> img2,"table" -> table)

  }

  def getBase64Str(imageFile: File): String = {
    val inputStream = new FileInputStream(imageFile)
    val bytes = IOUtils.toByteArray(inputStream)
    val bytes64 = Base64.encodeBase64(bytes)
    inputStream.close()
    new String(bytes64)
  }

}
